package org.boulderfoodrescue.webapp.client.pickups.newpickup;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.boulderfoodrescue.webapp.client.managers.TimeSlotManager;
import org.boulderfoodrescue.webapp.client.pickups.PickupInterface;
import org.boulderfoodrescue.webapp.client.pickups.selectors.CustomSelector;
import org.boulderfoodrescue.webapp.client.pickups.selectors.LocationSelectorTable;
import org.boulderfoodrescue.webapp.client.pickups.selectors.TimeSlotSelectorTable;
import org.boulderfoodrescue.webapp.client.pickups.selectors.VolunteerSelectorTable;
import org.boulderfoodrescue.webapp.shared.HasEventSummary;
import org.boulderfoodrescue.webapp.shared.HasEventSummary.EventType;
import org.boulderfoodrescue.webapp.shared.Location;
import org.boulderfoodrescue.webapp.shared.OneTimeEvent;
import org.boulderfoodrescue.webapp.shared.Pickup;
import org.boulderfoodrescue.webapp.shared.RecurringEvent;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails.AccessLevel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;

public class NewPickupView extends Composite{

	private static NewPickupViewUiBinder uiBinder = GWT
			.create(NewPickupViewUiBinder.class);

	interface NewPickupViewUiBinder extends UiBinder<Widget, NewPickupView> {
	}

	public NewPickupView(PickupInterface pickupInterface) {
		donorSelector = new CustomSelector<Location>(new LocationSelectorTable(), "Donor");
		donorTimeSlotSelector = new CustomSelector<HasEventSummary>(new TimeSlotSelectorTable(), "Donor Pickup Times");
		recipientSelector = new CustomSelector<Location>(new LocationSelectorTable(), "Recipient");
		recipientTimeSlotSelector = new CustomSelector<HasEventSummary>(new TimeSlotSelectorTable(), "Recipient Pickup Times");
		volunteerSelector = new CustomSelector<UserAccountDetails>(new VolunteerSelectorTable(), "Volunteer");
		initWidget(uiBinder.createAndBindUi(this));
		this.pickupInterface = pickupInterface;

		donorSelector.addHandler(new ValueChangeHandler<Location>(){
			@Override
			public void onValueChange(ValueChangeEvent<Location> event) {
				List<OneTimeEvent> oEvents = TimeSlotManager.getOneTimeTimeSlots(event.getValue());
				List<RecurringEvent> rEvents = TimeSlotManager.getRecurringTimeSlots(event.getValue());
				for(OneTimeEvent oe : oEvents){
					addTimeSlot(oe.getLocationKey(), oe);
				}
				for(RecurringEvent re : rEvents){
					addTimeSlot(re.getLocationKey(), re);
				}
				donorTimeSlotSelector.clear();
				if(timeSlot_map.get(event.getValue().getDatabaseKey()) != null){
					for(HasEventSummary e : timeSlot_map.get(event.getValue().getDatabaseKey())){
						donorTimeSlotSelector.addEntry(e);
					}
				}
			}
		}, ValueChangeEvent.getType());

		recipientSelector.addHandler(new ValueChangeHandler<Location>(){
			@Override
			public void onValueChange(ValueChangeEvent<Location> event) {
				List<OneTimeEvent> oEvents = TimeSlotManager.getOneTimeTimeSlots(event.getValue());
				List<RecurringEvent> rEvents = TimeSlotManager.getRecurringTimeSlots(event.getValue());
				for(OneTimeEvent oe : oEvents){
					addTimeSlot(oe.getLocationKey(), oe);
				}
				for(RecurringEvent re : rEvents){
					addTimeSlot(re.getLocationKey(), re);
				}
				recipientTimeSlotSelector.clear();
				if(timeSlot_map.get(event.getValue().getDatabaseKey()) != null){
					for(HasEventSummary e : timeSlot_map.get(event.getValue().getDatabaseKey())){
						recipientTimeSlotSelector.addEntry(e);
					}
				}
			}
		}, ValueChangeEvent.getType());
	}

	@UiField(provided = true) 
	CustomSelector<Location> donorSelector;
	@UiField(provided = true)
	CustomSelector<HasEventSummary> donorTimeSlotSelector;
	@UiField(provided = true)
	CustomSelector<Location> recipientSelector;
	@UiField(provided = true)
	CustomSelector<HasEventSummary> recipientTimeSlotSelector;
	@UiField(provided = true)
	CustomSelector<UserAccountDetails> volunteerSelector;
	@UiField
	TextArea notesTextArea;
	@UiField
	Button saveButton;
	@UiField
	Button cancelButton;
	@UiField
	ListBox transportationType;
	@UiField
	Label labelNoRecipient;
	@UiField
	CheckBox checkBoxNoRecipient;
	@UiField
	Label labelNoVolunteer;
	@UiField
	CheckBox checkBoxNoVolunteer;

	private Map<Long, List<HasEventSummary>> timeSlot_map = new HashMap<Long, List<HasEventSummary>>();

	private PickupInterface pickupInterface;

	private Pickup editing;

	@UiHandler("saveButton")
	public void onSaveButtonClick(ClickEvent event)
	{
		Pickup pickup;
		if(editing == null)
			pickup = new Pickup();
		else
			pickup = editing;

		if(donorSelector.getValue() == null){
			Window.alert("No donor selected");
			return;
		}
		else
			pickup.setDonor(donorSelector.getValue());
		
		if(recipientSelector.getValue() == null && !checkBoxNoRecipient.getValue()){
			Window.alert("No recipient selected");
			return;
		}
		else if(checkBoxNoRecipient.getValue())
			pickup.setRecipient(null);
		else
			pickup.setRecipient(recipientSelector.getValue());


		if(volunteerSelector.getValue() == null && !checkBoxNoVolunteer.getValue()){
			Window.alert("No volunteer selected");
			return;
		}
		else if(checkBoxNoVolunteer.getValue())
			pickup.setVolunteer(null);
		else
			pickup.setVolunteer(volunteerSelector.getValue());

		if(recipientTimeSlotSelector.getValue() == null && !checkBoxNoRecipient.getValue()){
			Window.alert("No recipient pickup time selected");
			return;
		}
		else if(checkBoxNoRecipient.getValue()){
			pickup.setOneTimeEventDropOff(null);
			pickup.setRecurringEventDropOff(null);
		}
		else if(recipientTimeSlotSelector.getValue().getEventType() == EventType.OneTime)
			pickup.setOneTimeEventDropOff((OneTimeEvent) recipientTimeSlotSelector.getValue());
		else
			pickup.setRecurringEventDropOff((RecurringEvent) recipientTimeSlotSelector.getValue());
		
		if(donorTimeSlotSelector.getValue() == null){
			Window.alert("No donor pickup time selected");
			return;
		}
		else if(donorTimeSlotSelector.getValue().getEventType() == EventType.OneTime)
			pickup.setOneTimeEventPickup((OneTimeEvent) donorTimeSlotSelector.getValue());
		else{
			pickup.setRecurringEventPickup((RecurringEvent) donorTimeSlotSelector.getValue());
			System.out.println(pickup.getRecurringEventPickupKey());
			System.out.println(pickup.getRecurringEventPickup());
			System.out.println(pickup.getRecurringEventPickup().getDatabaseKey());
		}
		
		pickup.setNotes(notesTextArea.getText());
		pickup.setTransportationViaLong(new Long(transportationType.getSelectedIndex()));

		pickupInterface.onNewPickupSave(pickup);
		editing = null;
	}

	@UiHandler("cancelButton")
	public void onCancelButtonClick(ClickEvent event)
	{
		pickupInterface.onNewPickupCancel();
	}

	//	@UiHandler("donorListBox")
	//	public void onDonorListBoxChange(ChangeEvent event)
	//	{
	//		donorTimeSlot.clear();
	//		Location donor = donor_map.get(donorListBox.getValue(donorListBox.getSelectedIndex()));
	//		List<RecurringEvent> rEvents = TimeSlotManager.getRecurringTimeSlots(donor);
	//		List<OneTimeEvent> oEvents = TimeSlotManager.getOneTimeTimeSlots(donor);
	//		
	//	}

	@UiHandler("checkBoxNoVolunteer")
	public void onCheckBoxNoVolunteer(ValueChangeEvent<Boolean> event){
		if(checkBoxNoVolunteer.getValue()){
			volunteerSelector.setVisible(false);
		} else{
			volunteerSelector.setVisible(true);
		}
	}

	@UiHandler("checkBoxNoRecipient")
	public void onCheckBoxNoRecipient(ValueChangeEvent<Boolean> event){
		if(checkBoxNoRecipient.getValue()){
			recipientSelector.setVisible(false);
			recipientTimeSlotSelector.setVisible(false);
		} else{
			recipientSelector.setVisible(true);
			recipientTimeSlotSelector.setVisible(true);
		}
	}

	@UiHandler("labelNoVolunteer")
	public void onLabelNoVolunteerClick(ClickEvent event){
		checkBoxNoVolunteer.setValue(!checkBoxNoVolunteer.getValue(), true);
	}

	@UiHandler("labelNoRecipient")
	public void onLabelNoRecipientClick(ClickEvent event){
		checkBoxNoRecipient.setValue(!checkBoxNoRecipient.getValue(), true);
	}

	public void setDonorsList(List<Location> donors)
	{
		donorSelector.clear();
		for(int i=0;i<donors.size();++i)
		{
			Location loc = donors.get(i);
			donorSelector.addEntry(loc);
		}
	}

	public void addTimeSlot(Long locationKey, HasEventSummary donorTimeSlot){
		List<HasEventSummary> list = timeSlot_map.get(locationKey);
		if(list == null)
			list = new LinkedList<HasEventSummary>();
		list.add(donorTimeSlot);
		if(donorSelector.getValue() != null && donorSelector.getValue().getDatabaseKey().longValue() == locationKey.longValue())
			donorTimeSlotSelector.addEntry(donorTimeSlot);
		else if(recipientSelector.getValue() != null && recipientSelector.getValue().getDatabaseKey().longValue() == locationKey.longValue())
			recipientTimeSlotSelector.addEntry(donorTimeSlot);
	}

	public void setRecipientList(List<Location> recipients)
	{
		recipientSelector.clear();
		for(int i=0;i<recipients.size();++i)
		{
			Location loc = recipients.get(i);
			recipientSelector.addEntry(loc);
		}
	}

	public void setVolunteerList(List<UserAccountDetails> volunteers)
	{
		volunteerSelector.clear();
		for(int i=0;i<volunteers.size();++i)
		{
			UserAccountDetails user = volunteers.get(i);
			if(user.getAccessLevel().compareTo(AccessLevel.Volunteer) >= 0)
			{
				volunteerSelector.addEntry(user);
			}
		}
	}

	public void clear() {
		donorSelector.setValue(null, false);
		recipientSelector.setValue(null, false);
		donorTimeSlotSelector.setValue(null, false);
		recipientTimeSlotSelector.setValue(null, false);
		volunteerSelector.setValue(null, false);
		transportationType.setSelectedIndex(0);
		notesTextArea.setValue("");
		checkBoxNoRecipient.setValue(false);
		checkBoxNoVolunteer.setValue(false);
	}

	public void setPickup(Pickup object) {
		donorSelector.setValue(object.getDonor());
		if(object.getOneTimeEventPickup() != null)
			donorTimeSlotSelector.setValue(object.getOneTimeEventPickup());
		else if(object.getRecurringEventPickup() != null)
			donorTimeSlotSelector.setValue(object.getRecurringEventPickup());
		else
			donorTimeSlotSelector.setValue(null, false);
		if(object.getRecipient() != null)
			recipientSelector.setValue(object.getRecipient());
		else
			recipientSelector.setValue(null, false);
		if(object.getOneTimeEventDropOff() != null)
			recipientTimeSlotSelector.setValue(object.getOneTimeEventPickup());
		else if(object.getRecurringEventDropOff() !=  null)
			recipientTimeSlotSelector.setValue(object.getRecurringEventDropOff());
		else
			recipientTimeSlotSelector.setValue(null, false);
		volunteerSelector.setValue(object.getVolunteer());
		transportationType.setSelectedIndex(object.getTransportationAsLong().intValue());
		notesTextArea.setText(object.getNotes());

		if(volunteerSelector.getValue() == null)
			checkBoxNoVolunteer.setValue(true, true);
		if(recipientSelector.getValue() == null)
			checkBoxNoRecipient.setValue(true, true);
		editing = object;
	}

}
